
const serviceUuid = 0xFFE0;
const characteristicUuid = 0xFFE1;

let rawData = [];
let memory = [];

let device = "";
let characteristic = "";

function textEncoder (string) {
    var encoder = new TextEncoder('utf-8');
    var result = encoder.encode(string);
    return result;
}

function textDecoder (value) {
    var decoder = new TextDecoder('utf-8');
    var result = decoder.decode(value);
    return result;
}

function log (value) {
    console.log(value);
}

function valueChangeHandler(event){
    let value = event.target.value;
    value = new Uint8Array(value.buffer);
    // log(value);
    rawData.push(...value);
    if (rawData.length >= 36){
        // log(rawData);
        extractData(rawData);
        rawData = [];
    }
}

function extractData(rawData) {
    let data = {};
    if (rawData[0] !== 0xFF) {
        log("rawData[0] error: "+rawData[0]);
        return;
    }
    if (rawData[1] !== 0x55) {
        log("rawData[1] error: "+rawData[1]);
        return;
    }
    if (rawData[2] !== 0x01) {
        log("rawData[2] error: "+rawData[2]);
        return;
    }
    if (rawData[3] !== 0x03) {
        log("rawData[2] error: "+rawData[3]);
        return;
    }
    log(rawData);
    data.voltage = ((rawData[4]<<16) + (rawData[5]<<8) + (rawData[6])) / 100;
    data.current = ((rawData[7]<<16) + (rawData[8]<<8) + (rawData[9])) / 100;
    data.watt = (data.voltage * data.current).toFixed(2);
    data.mah = ((rawData[10]<<16) + (rawData[11]<<8) + (rawData[12]));
    data.wh = ((rawData[13]<<24) + (rawData[14]<<16) + (rawData[15]<<8) + (rawData[16])) / 100;
    data.timestamp = rawData[0x18] + ":" + rawData[0x19] + ":" + rawData[0x1A];
    log(data.current);
    memory.push(data);
    console.log(data);
    printData(data);
}

function printData(data) {
    for (var key in data){
        document.querySelector(`#${key}`).innerHTML = data[key];
    }
}

async function connect(){
    document.querySelector(`#connect`).innerHTML = "connecting";
    device = await navigator.bluetooth.requestDevice({
        filters: [{services: [serviceUuid]}]
    });
    log('Connecting to GATT Server...');
    const server = await device.gatt.connect();

    log('Getting Service...');
    const service = await server.getPrimaryService(serviceUuid);

    log('Getting Characteristic...');
    characteristic = await service.getCharacteristic(characteristicUuid);

    characteristic.addEventListener('characteristicvaluechanged', valueChangeHandler);
    document.querySelector(`#connect`).innerHTML = "disconnect";
    document.querySelector(`#connect`).onclick = disconnect;
}
async function disconnect(){
    await device.gatt.disconnect();
    document.querySelector(`#connect`).innerHTML = "connect";
    document.querySelector(`#connect`).onclick = connect;
}

async function start(){
    rawData = [];
    characteristic.startNotifications();
    const reset_cmd = new Uint8Array([0xff, 0x55, 0x11, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00, 0x5d]);
    characteristic.writeValue(reset_cmd);
}

async function stop(){
    rawData = [];
    characteristic.stopNotifications();
}

async function download () {
    let csvContent = "data:text/csv;charset=utf-8,";
    csvContent += Object.keys(memory[0]).join(',') + "\n";
    for (var i=0; i<memory.length; i++) {
        csvContent += Object.values(memory[i]).join(",")+ "\n";
    }
    var encodedUri = encodeURI(csvContent);
    var link = document.createElement("a");
    link.setAttribute("href", encodedUri);
    link.setAttribute("download", "data.csv");
    document.body.appendChild(link); // Required for FF
    
    link.click();
}